﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace YinLongTool.Security
{
	public class RSAHelper
	{
		public void RSAKey(string PrivateKeyPath, string PublicKeyPath)
		{
			try
			{
				RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
				CreatePrivateKeyXML(PrivateKeyPath, rSACryptoServiceProvider.ToXmlString(true));
				CreatePublicKeyXML(PublicKeyPath, rSACryptoServiceProvider.ToXmlString(false));
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public string GetHash(string m_strSource)
		{
			HashAlgorithm hashAlgorithm = HashAlgorithm.Create("MD5");
			byte[] bytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
			byte[] inArray = hashAlgorithm.ComputeHash(bytes);
			return Convert.ToBase64String(inArray);
		}

		public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
		{
			try
			{
				using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
				{
					rSACryptoServiceProvider.FromXmlString(xmlPublicKey);
					byte[] bytes = System.Text.Encoding.UTF8.GetBytes(m_strEncryptString);
					int num = rSACryptoServiceProvider.KeySize / 8 - 11;
					if (bytes.Length > num)
					{
						using (MemoryStream memoryStream = new MemoryStream(bytes))
						{
							using (MemoryStream memoryStream2 = new MemoryStream())
							{
								byte[] array = new byte[num];
								for (int num2 = memoryStream.Read(array, 0, num); num2 > 0; num2 = memoryStream.Read(array, 0, num))
								{
									byte[] array2 = new byte[num2];
									Array.Copy(array, 0, array2, 0, num2);
									byte[] array3 = rSACryptoServiceProvider.Encrypt(array2, false);
									memoryStream2.Write(array3, 0, array3.Length);
								}
								return Convert.ToBase64String(memoryStream2.ToArray(), Base64FormattingOptions.None);
							}
						}
					}
					return Convert.ToBase64String(rSACryptoServiceProvider.Encrypt(bytes, false));
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
		{
			try
			{
				using (RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider())
				{
					rSACryptoServiceProvider.FromXmlString(xmlPrivateKey);
					byte[] array = Convert.FromBase64String(m_strDecryptString);
					int num = rSACryptoServiceProvider.KeySize / 8;
					if (array.Length > num)
					{
						using (MemoryStream memoryStream = new MemoryStream(array))
						{
							using (MemoryStream memoryStream2 = new MemoryStream())
							{
								byte[] array2 = new byte[num];
								for (int num2 = memoryStream.Read(array2, 0, num); num2 > 0; num2 = memoryStream.Read(array2, 0, num))
								{
									byte[] array3 = new byte[num2];
									Array.Copy(array2, 0, array3, 0, num2);
									byte[] array4 = rSACryptoServiceProvider.Decrypt(array3, false);
									memoryStream2.Write(array4, 0, array4.Length);
								}
								return System.Text.Encoding.UTF8.GetString(memoryStream2.ToArray());
							}
						}
					}
					return System.Text.Encoding.UTF8.GetString(rSACryptoServiceProvider.Decrypt(array, false));
				}
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}
		/// <summary>
		/// 签名
		/// </summary>
		/// <param name="p_strKeyPrivate"></param>
		/// <param name="m_strHashbyteSignature"></param>
		/// <returns></returns>
		public string SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature)
		{
			byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
			RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
			rSACryptoServiceProvider.FromXmlString(p_strKeyPrivate);
			RSAPKCS1SignatureFormatter rSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rSACryptoServiceProvider);
			rSAPKCS1SignatureFormatter.SetHashAlgorithm("MD5");
			byte[] inArray = rSAPKCS1SignatureFormatter.CreateSignature(rgbHash);
			return Convert.ToBase64String(inArray);
		}
		/// <summary>
		/// 签名验证
		/// </summary>
		/// <param name="p_strKeyPublic"></param>
		/// <param name="p_strHashbyteDeformatter"></param>
		/// <param name="p_strDeformatterData"></param>
		/// <returns></returns>
		public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
		{
			try
			{
				byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
				RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
				rSACryptoServiceProvider.FromXmlString(p_strKeyPublic);
				RSAPKCS1SignatureDeformatter rSAPKCS1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rSACryptoServiceProvider);
				rSAPKCS1SignatureDeformatter.SetHashAlgorithm("MD5");
				byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
				if (rSAPKCS1SignatureDeformatter.VerifySignature(rgbHash, rgbSignature))
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		public void CreatePublicKeyXML(string path, string publickey)
		{
			try
			{
				FileStream fileStream = new FileStream(path, FileMode.Create);
				StreamWriter streamWriter = new StreamWriter(fileStream);
				streamWriter.WriteLine(publickey);
				streamWriter.Close();
				fileStream.Close();
			}
			catch
			{
				throw;
			}
		}

		public void CreatePrivateKeyXML(string path, string privatekey)
		{
			try
			{
				FileStream fileStream = new FileStream(path, FileMode.Create);
				StreamWriter streamWriter = new StreamWriter(fileStream);
				streamWriter.WriteLine(privatekey);
				streamWriter.Close();
				fileStream.Close();
			}
			catch
			{
				throw;
			}
		}

		public string ReadPublicKey(string path)
		{
			StreamReader streamReader = new StreamReader(path);
			string result = streamReader.ReadToEnd();
			streamReader.Close();
			return result;
		}

		public string ReadPrivateKey(string path)
		{
			StreamReader streamReader = new StreamReader(path);
			string result = streamReader.ReadToEnd();
			streamReader.Close();
			return result;
		}
	}

}
